Создаем пользовательскую визуализацию в Kibana 7.1.1

Предисловие
В процессе разработки наша команда столкнулась с тем, что не так уж и много инструкций или “туториалов” по созданию собственной визуализации.
Конечно, существует официальная документация по разработке визуализации, но, как мне кажется, она недостаточно удобна и подробна.
В этой статье я опишу процесс создания визуализации как отдельного плагина на kibana 7.1.*.
Создаем плагин
Для этого переходим в папку kibana/plugins
Создаем папку для нашего плагина.
В нашей папке создаем:
package.jsonindex.jspublic (директория)
В package.json:
name– имя плагина.version– версия Kibana, в которой будет работать плагин.description– описание.main– имя главного файла плагина.
{
"name": "SM_tutorial_vis",
"version": "7.1.1",
"description": "SM_tutorial_vis",
"main": "index.js"
}В index.js:
Мы объявляем новый плагин Kibana, который будет являться визуализацией. Не забываем указывать правильное имя!
export default function (kibana) {
return new kibana.Plugin({
uiExports: {
visTypes: [
'plugins/SM_tutorial_vis/SM_tutorial_vis'
]
},
});
}Создаем визуализацию
Переходим в папку /public.
Cоздаем необходимые файлы:
SM_tutorial_vis.jsSM_tutorial_vis_controller.jsSM_tutorial_vis_editor.htmlSM_tutorial_vis.less
SM_tutorial_vis.js
В этом файле создается сама визуализация, а также прописываются необходимые настройки и параметры.
Делаем необходимые импорты:
import { VisFactoryProvider } from 'ui/vis/vis_factory';
import { VisTypesRegistryProvider } from 'ui/registry/vis_types';
import { Schemas } from 'ui/vis/editors/default/schemas';
import './SM_tutorial_vis.less';
import optionsTemplate from './SM_tutorial_vis_editor.html';
import { SmTutorialController } from './SM_tutorial_vis_controller';Опишем функцию SmTutorialVis, в которой создадим визуализацию, с помощью объекта класса VisFactoryProvider:
function SmTutorialVis(Private) {
const VisFactory = Private(VisFactoryProvider);
return VisFactory.createBaseVisualization({ //Создаем визуализацию
...
});
}Существует несколько VisFactoryProvider помимо BaseVisualisation:
AngularVisTypeReactVisTypeVislibVisType
Далее опишем нашу визуализацию:
return VisFactory.createBaseVisualization({
name: 'SM_tutorial_vis', // Имя визуализации
type: 'metric', // Тип визуализации
title: 'SM tutorial', // Заголовок, который будет написан в kibana
icon: 'smVis', // Иконка EUI
description: 'This is visualisation from volgablob tutorial', // Описание
visualization: SmTutorialController, //Класс контроллер, в котором опишем логикуДалее указывается словарь visConfig, в котором можем задать любые параметры, которые нам пригодятся в контроллере. Эти параметры будут проинициализированы нашими значениями при создании визуализации.
Они также могут быть использованы во вкладке Options в самой Kibana при создании визуализации.
visConfig: {
defaults: {
metricTitle: null,
fontSize: 40,
titleIndicator: 'SM title',
volgablob: 'VolgaBlob'
},
},Следующим указываем словарь editorConfig, в котором можно указать шаблон вкладки Options и указать схему:
editorConfig: {
optionsTemplate: optionsTemplate, //html шаблон вкладки Options
//Схема, которая будет использована для визуализации
//Можно указать metrics, buckets и тд
schemas: new Schemas([
{
group: 'metrics',
name: 'metric',
title: 'Metric',
aggFilter: ['max'], //Фильтр доступных агрегаций. Можно испольвать '!avg', тогда будут все, кроме avg
min: 1, //Минимальное количество метрик
max: 1, //Максимальное количество метрик
defaults: [
{ type: 'max', schema: 'metric' } //Стандартное значение метрики
]
}
])
},
});
}И последняя часть в этом файле, но не по значимости!
Регистрируем нашу визуализацию c помощью VisTypesRegistryProvider.
Как параметр, передаем созданную нами функцию SmTutorialVis:
VisTypesRegistryProvider.register(SmTutorialVis);
Логика визуализации
SM_tutorial_vis_controller.js
- Создаем класс, который мы описывали как контроллер в
SM_tutorial_vis.js
Начинаем с конструктора:
class SmTutorialController {
constructor(el, vis) {
this.el = el;
this.vis = vis;
this.container = document.createElement('div');
this.container.className = 'smTutorial';
this.el.appendChild(this.container);
this.metricValue = null;
}Опишем метод render.
Это основной метод, который нарисует нашу визуализацию. В этом примере мы создадим обычный div, внутри которого будет рендерится визуализация.
render(visData, status) {
this.container.innerHTML = '';
const table = visData;
const metrics = [];
let bucketAgg;
table.columns.forEach((column, i) => {
table.rows.forEach(row => {
const value = row[i];
metrics.push({
title: bucketAgg ? `${row[0]} ${column.title}` : column.title,
value: row[column['id']],
formattedValue: column.aggConfig ? column.aggConfig.fieldFormatter('text')(value) : value,
bucketValue: bucketAgg ? row[0] : null,
aggConfig: column.aggConfig
});
});
});Здесь стоит обратить внимание на параметр visData. Там хранится вся необходимая информация о метрике, а именно: значение, тип агрегации, пользовательский лейбл и тд. В зависимости от этих данных мы и будем вставлять нашу html разметку.
Также здесь мы формируем массив metrics для удобства работы с данными далее.
Давайте пройдемся по массиву metrics и создадим блоки div для отображения нашей визуализации:
metrics.forEach(metric => {
this.metricValue = metric.value;
var title = metric.aggConfig.params.customLabel;
//Если изменено название и оно не пустое
if(!title) {
title = "SM tutorial";
}
const metricDiv = document.createElement(`div`);
...
metricDiv.innerHTML = `<div class="icon">${icon}</div> <div class="desc">${title}</div>`;
});И не забываем вернуть Promise:
return new Promise(resolve => {
resolve('Done rendering');
});
}Добавляем метод destroy:
destroy() {
this.el.innerHTML = '';
console.log('Destroying');
}
};Экспортируем наш класс:
export { SmTutorialController };Разметка вкладки options
SM_tutorial_vis_editor_editor.html
Здесь мы можем отредактировать вкладку Options, чтобы сделать поля для дополнительных настроек визуализации.
<div class="form-group"> <label> Размер шрифта</label> <input type="number" ng-model="vis.params.fontSize" class="form-control"/> </div> <div class="form-group"> <label>Заголовок индикатора</label> <input type="text" ng-model="vis.params.titleIndicator" class="form-control"/> </div>
vis.params.* – поля, которые мы задавали в SM_tutorial_vis.js в словаре visConfig.
Cтили
SM_tutorial_vis.less
Простой less файл, который позволит добавить нашей визуализации немного красоты и каскадных таблиц :).
После этого можно запускать kibana и наслаждаться новой визуализацией!